#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/select.h>
#include <arpa/inet.h>

#define MAX_BUFFER 1024

// 全局写缓冲区和长度数组
char write_buf[MAX_BUFFER];
int write_len = 0;
int need_write = 0; // 简化示例，仅处理单个客户端

int main() {
    int listenfd, connfd, sockfd, maxfd, nready;
    fd_set rset, wset, allrset, allwset;
    struct sockaddr_in servaddr, cliaddr;
    socklen_t clilen;
    char buf[MAX_BUFFER];

    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(9999);
    bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    listen(listenfd, 20);

    maxfd = listenfd;
    // FD_ZERO(fd_set* fdset)： 将fd_set变量的所有位初始化为0。
    // FD_CLR(int fd，fd_set *set)：清除fd_set集合中指定的fd文件描述符。
    // FD_SET(int fd，fd_set *set)：在fd_set集合中注册文件描述符fd的信息。
    // FD_ISSET(int fd, fd_set* fdset)：若参数fd_set指向的变量中包含文件描述符fd的信息，则返回真。

    FD_ZERO(&allrset);
    FD_ZERO(&allwset);
    FD_SET(listenfd, &allrset);

    printf("[Server] Listening on port 9999...\n");

    while (1) {
        rset = allrset;
        wset = allwset;
        nready = select(maxfd + 1, &rset, &wset, NULL, NULL);
        if (FD_ISSET(listenfd, &rset)) {
            clilen = sizeof(cliaddr);
            connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
            printf("[Event] New connection accepted (fd=%d)\n", connfd);
            printf("client ip is %s\n",inet_ntoa(cliaddr.sin_addr));
            FD_SET(connfd, &allrset);
            if (connfd > maxfd) maxfd = connfd;
        }
        // 遍历所有可能的文件描述符
        for (int i = 0; i <= maxfd; i++) {
            if (i == listenfd) continue; // 跳过监听套接字
            if (FD_ISSET(i, &rset)) {
                int n = read(i, buf, sizeof(buf));
                if (n <= 0) {
                    // 连接关闭或错误
                    printf("[Event] Client fd=%d disconnected\n", i);
                    printf("client ip is %s\n",inet_ntoa(cliaddr.sin_addr));
                    close(i);
                    FD_CLR(i, &allrset);
                    FD_CLR(i, &allwset);
                    need_write = 0;
                } else {
                    // 接收数据并准备回写
                    printf("[Data] Received %d bytes from fd=%d: %.*s\n", 
                        n, i, n, buf);
                    // 保存数据到写缓冲区并注册写事件
                    memcpy(write_buf, buf, n);
                    write(i, buf, n);
                    FD_SET(i, &allwset);
                }
            }

            /* ---------- 处理写事件 ---------- */
            if (FD_ISSET(i, &wset) && need_write) {
                int sent = write(i, write_buf, write_len);
                if (sent > 0) {
                    printf("[Data] Sent %d bytes to fd=%d\n", sent, i);
                    need_write = 0;
                    FD_CLR(i, &allwset); // 取消写监控
                } else {
                    perror("write error");
                }
            }
        }
    }
    return 0;
}